/**
 * A singular factory that contains all of the DateTime-factories needed fro date-time processing.
 */
package org.hackystat.ui.telemetryviewer.client;

import java.util.Date;

import com.google.gwt.i18n.client.DateTimeFormat;

/**
 * A singular factory that contains all of the DateTime-factories needed for date-time processing.
 * @author David J. Nickles
 * 
 */
public class DateTimeFactories {
  
  private static DateTimeFactories singular;
  
  private DateTimeFormat xmlfactory;
  private DateTimeFormat zonefactory;
  private DateTimeFormat headerfactory;
  private DateTimeFormat bodyfactory;
  private DateTimeFormat timefactory;
  private DateTimeFormat datefactory;

  /**
   * Construct all the DataTime Factories.
   */
  private DateTimeFactories() {
    initDateTimeFactories();
  }
  
  /**
   * This method constructs the DateTimeFactories that will be used to manipulate timestamps.
   */
  private void initDateTimeFactories() {
    this.xmlfactory = DateTimeFormat.getFormat("yyyy-MM-dd'T'HH:mm:ssZ");
    this.zonefactory = DateTimeFormat.getFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
    this.headerfactory = DateTimeFormat.getFormat("EEE, MMM dd, h:mma");
    this.bodyfactory = DateTimeFormat.getFormat("EEE, MMM dd, h:mm:ssa");
    this.timefactory = DateTimeFormat.getFormat("h:mm:ssa");
    this.datefactory = DateTimeFormat.getFormat("yyyy-MM-dd");
  }
  
  /**
   * @return a singular reference to a SDVDateTimeFactory that this class maintains.
   */
  public static DateTimeFactories getInstance() {
    if (singular == null) {
      return (singular = new DateTimeFactories());
    } 
    else {
      return singular;
    }
  }

  /**
   * @return the datefactory
   */
  public DateTimeFormat getDatefactory() {
    return datefactory;
  }

  /**
   * @return the bodyfactory
   */
  public DateTimeFormat getBodyfactory() {
    return bodyfactory;
  }

  /**
   * @return the headerfactory
   */
  public DateTimeFormat getHeaderfactory() {
    return headerfactory;
  }

  /**
   * @return the timefactory
   */
  public DateTimeFormat getTimefactory() {
    return timefactory;
  }

  /**
   * @return the xmlfactory
   */
  public DateTimeFormat getXmlfactory() {
    return xmlfactory;
  }

  /**
   * @return the zonefactory
   */
  public DateTimeFormat getZonefactory() {
    return zonefactory;
  }
  
  /**
   * This method will format the time into the appropriate XML Schema time format
   * yyyy-MM-dd'T'hh:mm:ss.SSS ex. 2007-04-30T09:00:00-10:00.
   * @param date the request event date and time
   * @return String Formatted string of the time in proper XML Schema time format.
   */
  private static String toXMLFormat(Date date) {
    String timestamp = getInstance().getXmlfactory().format(date);
    /* GWT bug does not put the : in the time zone value which is needed 
     * on the Java side by XMLGregorianCalendar lexical parser. */
    String javaZoneDate = new String(timestamp.substring(0, timestamp.length() - 2) + ":"
        + timestamp.substring(timestamp.length() - 2, timestamp.length()));
    return javaZoneDate;
  }

  /**
   * Returns a String in XML-standard-format corresponding to the current date/time.
   * @return Returns a String in XML-standard-format corresponding to the current date/time.
   */
  public static String makeTimestamp() {
    return toXMLFormat(new Date());
  }
}
